#include <iostream>
using namespace std;

class point
{
    int x;
    int y;
    friend ostream &operator<<(ostream &cout, const point &m_p); //定义为·私有也行

    friend istream &operator>>(istream &m_cin, point &m_p);

public:
    point(int m_x = 0, int m_y = 0) : x(m_x), y(m_y){};
    //friend ostream &operator<<(ostream &cout, const point &m_p);//友元函数不属于类，所以不受所在类的声明区域public ，private，protected的影响，定义在类的任何区域都可以
};

//  1-左移运算符是连续返回左值给cout,   cout<<1<<2<<3; 相当于  先进行cout<<1, 把1返回给cout,即(cout<<1)返回cout,再进行(cout<<1)<<2,也就是cout<<2，
//  最后进行((cout<<1)<<2)<<3.所以左移运算符的返回值是cout.
//  2-而且默认重载的左移运算符的左边是非const,所以我们再次重载的时候，也要保证<<左边是非const.
ostream &operator<<(ostream &m_cout, const point &m_p) //m_cout要保证为非const,如果定义成全局函数则不能使用const限定函数为常函数，那自然返回值也不能是const类型，因为返回的常对象在返回给cout时，要保证<<左边不是const
{
    m_cout << m_p.x << m_p.y;
    return m_cout;
}

istream &operator>>(istream &m_cin, point &m_p) //因为输入数据的操作就是在改变传入参数的过程，所以不要加const修饰point&m_p
{
    m_cin >> m_p.x >> m_p.y;
    return m_cin;
}
int main()
{
    point p1(3, 4);
    point p2(1, 3);
    cout << p1 << p2 << endl; //如果左移运算符返回值是const，就会报错
    point p3;
    point p4;
    cin >> p3 >> p4;
    cout << p3 << p4 << endl;
}
